Syntax10.Scn.Fnt Syntax10b.Scn.Fnt FoldElems MODULE MinesElems; (** Oberon-MinesElem V1.32 (C) 1 Oct 95 by Ralf Degner *) IMPORT Texts, TextFrames, Mines, Oberon, Display, Printer, TextPrinter, Files; TYPE Elem = POINTER TO ElemDesc; ElemDesc = RECORD (Texts.ElemDesc) d: Mines.Data; END; Frame = POINTER TO FrameDesc; FrameDesc = RECORD (Mines.FrameDesc) col: INTEGER; e: Elem; END; W: Texts.Writer; (* print the element *) PROCEDURE Print(e: Elem; x0, y0: INTEGER); VAR w, h: INTEGER; FontName, Ausgabe: ARRAY 32 OF CHAR; BEGIN w:=SHORT(e.W DIV TextPrinter.Unit); h:=SHORT(e.H DIV TextPrinter.Unit); FontName:="Syntax16.Scn.Fnt"; Printer.ReplPattern(x0, y0, w, h, 2); Printer.Line(x0, y0, x0+w, y0); Printer.Line(x0, y0, x0, y0+h); Printer.Line(x0+w, y0, x0+w, y0+h); Printer.Line(x0, y0+h, x0+w, y0+h); Ausgabe:="Oberon-Mines"; IF e.d.XKastenAnz<8 THEN FontName:="Syntax14.Scn.Fnt"; END; Printer.String(x0+11, y0+h DIV 2-15, Ausgabe, FontName); END Print; (* draw all *) PROCEDURE PlotAll(f: Frame); VAR XDum, YDum: INTEGER; BEGIN Oberon.RemoveMarks(f.SeitenOffset, f.UntenOffset, f.W, f.H); Display.ReplConst(f.col, f.SeitenOffset, f.UntenOffset, f.W-2, f.H-2, Display.replace); FOR XDum:=1 TO f.d.XKastenAnz DO FOR YDum:=1 TO f.d.YKastenAnz DO Mines.DrawKasten(f, XDum, YDum, FALSE, f.col) END END END PlotAll; (* create new field *) PROCEDURE NewField(XAnz, YAnz, Quote, Mode: INTEGER): Mines.Data; VAR d: Mines.Data; BEGIN NEW(d); d.Aktiv:=TRUE; d.Pause:=FALSE; d.StartPlay:=FALSE; d.XKastenAnz:=XAnz; d.YKastenAnz:=YAnz; d.Quote:=Quote; d.Mode:=Mode; Mines.NeuesFeld(d, d.XKastenAnz, d.YKastenAnz); RETURN d; END NewField; (* do mouseaction for frame*) PROCEDURE DoMouse(g: Mines.Frame; X, Y: INTEGER; Key, FirstKey: SET); VAR XKasten, YKasten: INTEGER; f: Frame; BEGIN f:=g(Frame); IF FirstKey={1} THEN IF Key={1,0} THEN Mines.Score() ELSIF Key={2,1} THEN IF (~f.d.Aktiv) OR (f.d.Aktiv & f.d.StartPlay) THEN f.d:=NewField(f.d.XKastenAnz, f.d.YKastenAnz, f.d.Quote, f.d.Mode); f.e.d:=f.d; PlotAll(f) END ELSIF Key={1} THEN IF f.d.Aktiv & f.d.StartPlay THEN Texts.WriteString(W, "Mines to find: "); Texts.WriteInt(W, f.d.Mines, 1); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END END; RETURN; END; X:=X-f.SeitenOffset;Y:=Y-f.UntenOffset; IF X<0 THEN RETURN;END; IF Y<0 THEN RETURN;END; XKasten:=X DIV Mines.KastenPlatz +1; YKasten:=Y DIV Mines.KastenPlatz +1; IF (XKasten<=f.d.XKastenAnz) & (YKasten<=f.d.YKastenAnz) THEN IF f.d.Aktiv THEN IF (X MOD Mines.KastenPlatz)=0 THEN RETURN;END; IF (Y MOD Mines.KastenPlatz)=0 THEN RETURN;END; Oberon.RemoveMarks(f.SeitenOffset, f.UntenOffset, f.W, f.H); Mines.MouseKeys(f, XKasten, YKasten, Key, FALSE, f.col); IF f.d.Count=0 THEN Texts.WriteString(W, "You've got it ! Time: "); Texts.WriteInt(W, f.d.Time, 1); Texts.WriteString(W, " sec."); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END END END END DoMouse; (* handler for Frame *) PROCEDURE FrameHandler(msgf: Display.Frame; VAR msg: Display.FrameMsg); VAR f: Frame; BEGIN f:=msgf(Frame); WITH msg: Oberon.InputMsg DO IF msg.id=Oberon.track THEN f.UntenOffset:=f.Y+1;f.SeitenOffset:=f.X+1; Mines.TrackMouse(f, msg.X, msg.Y, msg.keys, DoMouse) END | msg: Mines.PlotKastenMsg DO IF msg.d=f.d THEN Mines.DrawKasten(f, msg.x, msg.y, FALSE, f.col) END ELSE END END FrameHandler; (* create new Frame *) PROCEDURE NewFrame(d: Mines.Data; X0, Y0: INTEGER): Frame; VAR f: Frame; BEGIN NEW(f); f.handle:=FrameHandler; f.d:=d; f.X:=X0; f.Y:=Y0; f.W:=d.XKastenAnz*Mines.KastenPlatz+3; f.H:=d.YKastenAnz*Mines.KastenPlatz+3; f.SeitenOffset:=X0+1;f.UntenOffset:=Y0+1; RETURN f; END NewFrame; (* load element state *) PROCEDURE Load(e: Elem; VAR r: Files.Rider); VAR XAnz, YAnz, Quote, Mode: SHORTINT; BEGIN Files.Read(r, XAnz); Files.Read(r, YAnz); Files.Read(r, Quote); Files.Read(r, Mode); e.d:=NewField(XAnz, YAnz, Quote, Mode); END Load; (* store element state *) PROCEDURE Store(e: Elem; VAR r: Files.Rider); BEGIN Files.Write(r, SHORT(e.d.XKastenAnz)); Files.Write(r, SHORT(e.d.YKastenAnz)); Files.Write(r, SHORT(e.d.Quote)); Files.Write(r, SHORT(e.d.Mode)); END Store; (* mouseaction, if not selected *) PROCEDURE MouseAction(g: Mines.Frame; X, Y: INTEGER; keys, FirstKey: SET); BEGIN IF (keys={0,1}) OR (keys={1,2}) THEN Mines.Open()END END MouseAction; (* handler for element *) PROCEDURE Handle(HanElem: Texts.Elem; VAR msg: Texts.ElemMsg); VAR copy: Elem; e: Elem; f: Frame; BEGIN e:=HanElem(Elem); WITH msg: Texts.CopyMsg DO NEW(copy); Texts.CopyElem(e, copy); copy.d:=NewField(e.d.XKastenAnz, e.d.YKastenAnz, e.d.Quote, e.d.Mode); msg(Texts.CopyMsg).e:=copy | msg: Texts.IdentifyMsg DO msg.mod:="MinesElems"; msg.proc:="Alloc" | msg: TextFrames.DisplayMsg DO IF ~msg.prepare THEN f:=NewFrame(e.d, msg.X0, msg.Y0); f.col:=msg.col;f.e:=e; PlotAll(f); msg.elemFrame:=f END | msg: TextFrames.TrackMsg DO Mines.TrackMouse(f, msg.X, msg.Y, msg.keys, MouseAction) | msg: TextPrinter.PrintMsg DO IF ~msg.prepare THEN Print(e, msg.X0, msg.Y0) END | msg: Texts.FileMsg DO IF msg.id=Texts.load THEN Load(e, msg.r) ELSIF msg.id=Texts.store THEN Store(e, msg.r) END ELSE END END Handle; (* build new element *) PROCEDURE Build(Quote, XKasten, YKasten, Mode: INTEGER); VAR e: Elem; M: TextFrames.InsertElemMsg; BEGIN Mines.GetPar(Quote, XKasten, YKasten, Mode); NEW(e); e.W:=LONG(XKasten*Mines.KastenPlatz+3)*TextFrames.Unit; e.H:=LONG(YKasten*Mines.KastenPlatz+3)*TextFrames.Unit; e.handle:=Handle; e.d:=NewField(XKasten, YKasten, Quote, Mode); M.e:=e; Oberon.FocusViewer.handle(Oberon.FocusViewer, M) END Build; (* allocator for loaded element *) PROCEDURE Alloc*; VAR e: Elem; BEGIN NEW(e); e.handle:=Handle; Texts.new:=e END Alloc; (* insert different elements *) PROCEDURE Insert*; BEGIN Build(15, 8, 8, -1); END Insert; PROCEDURE Beginner*; BEGIN Build(15, 8, 8, 0); END Beginner; PROCEDURE Advanced*; BEGIN Build(16, 16, 16, 1); END Advanced; PROCEDURE Expert*; BEGIN Build(21, 30, 16, 2); END Expert; BEGIN Texts.OpenWriter(W) END MinesElems.